/***************************************************************************
Name:		clientmanager.cpp
Autor:		Kevin Huber
Version:	1.0
Last Edit:      17.07.2009

Beschreibung:
Verwaltet die Client Objekte.
***************************************************************************/

#include "clientmanager.h"
#include "chathandler.h"
#include "sqlconnectiondata.h"

ClientManager::ClientManager(QObject *parent) : QObject(parent)
{
    m_console.addStatusMessage("Create SQLConnection...");
    m_TunnelDatabase = new SQLConnection(this, DB_TUNNEL_DBNAME, DB_TUNNEL_USER, DB_TUNNEL_PASSWD, DB_TUNNEL_HOST, DB_TUNNEL_PORT);

    if( !m_TunnelDatabase )
        m_console.addErrorMessage("Cannot create SQLConnection!");
    else
        m_console.addStatusMessage("SQLConnection successfully created!");


    connectedClients = 0;
    m_firstClient    = NULL;
    m_lastClient     = NULL;
}

ClientManager::~ClientManager()
{
    m_console.addStatusMessage("ClientManager is shutingdown!");
    m_console.addStatusMessage("Disconnecting all clients(%d)...", connectedClients);

    while( clientsConnected() )
    {
        if( !m_firstClient )
            break;

        m_console.addMessage("-> Disconnecting client with ID %d", m_firstClient->getId());

        removeClient(m_firstClient, "Server shutdown..");
    }

    m_console.addStatusMessage("All clients got disconnected.");

    delete m_TunnelDatabase;
    m_console.addStatusMessage("ClientManager terminated successfully.");
}

Client *ClientManager::newClient(QTcpSocket *socket, Client_Status cStatus)
{
    // Add a new client in our managed list
    Client *client = new Client(this, 0, socket, m_TunnelDatabase, cStatus, this);

    connect(client, SIGNAL(signal_disconnected(Client*)), this, SLOT(on_ClientDisconnected(Client*)));
    connect(client->getChatHandler(), SIGNAL(error(const QString&)), this, SLOT(on_clientError(const QString&)));

    if( !m_firstClient )
        m_firstClient = client;

    if( m_lastClient )
    {
        m_lastClient->setNextClient(client);
        client->setLastClient(m_lastClient);
    }

    m_lastClient = client;

    m_console.addMessage("Added new Client(Id: %d).", client->getId());

    connectedClients++;
    return client;
}

void ClientManager::removeClient(const quint32 &cId, QString reason)
{
    Client *clientToRemove = getClient(cId);

    if( !clientToRemove )
    {
        m_console.addErrorMessage("No Client with ID %d found!", cId);

        return;
    }

    removeClient(clientToRemove, reason);
}

void ClientManager::removeClient(Client *clientToRemove, QString reason)
{
    if( !clientToRemove )
    {
        m_console.addErrorMessage("Cannot remove client:\"Unknown client.\"");

        return;
    }

    // Disconnection signals from client to clientmanager
    disconnect(clientToRemove, SIGNAL(signal_disconnected(Client*)), this, SLOT(on_ClientDisconnected(Client*)));

    quint32 cId = clientToRemove->getId();

    if( clientToRemove == m_firstClient )
        m_firstClient = clientToRemove->getNextClient();

    if( clientToRemove == m_lastClient )
        m_lastClient = m_lastClient->getLastClient();

    connectedClients--;
    delete clientToRemove;

    m_console.addMessage("Client %d got disconnected(Reason: %s).", cId, reason.toStdString().c_str());
}

void ClientManager::on_clientError(const QString &error)
{
    m_console.addErrorMessage(error.toStdString().c_str());
}
